<template>
  <div
    ref="chartContainerElRef"
    class="w-full h-auto origin-top-left min-w-600px flex flex-col justify-start items-start overflow-x-auto select-none"
    :class="`${classname}`"
  >
    <svg
      ref="svgElRef"
      class="w-full h-full"
      @click="handleSVGElementClick"
    ></svg>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, onUpdated, ref } from "vue";
// For customizing multi mode chart: base on create date or timeline, we have rewrited the chart.xkcd's XY chart with TypeScript.
// Here are some reasons about this motivation.
//
// The shortcomings of the old chart.xkcd (project link: https://github.com/timqian/chart.xkcd):
// 1. The X axis label string could be only formatted date or raw text;
// 2. It's difficult/not possible to debug and customize;
//
// The advantages of the new one:
// 1. Writing in native TypeScript;
// 2. Easy to debug chart internal;
// 3. Totally customizable.
import XYChart, { XYChartData } from "../../../packages/xy-chart";
import { MIN_CHART_WIDTH } from "../../helpers/consts";

const props = defineProps({
  classname: {
    type: String,
    default: "",
  },
  data: {
    type: Object as () => XYChartData,
  },
  chartMode: {
    type: String,
    default: "Date",
  },
  timeFormat: String,
});

const chartContainerElRef = ref<HTMLDivElement>();
const svgElRef = ref<SVGSVGElement>();

const drawStarChart = (data: XYChartData) => {
  if (svgElRef.value) {
    svgElRef.value.innerHTML = "";

    XYChart(
      svgElRef.value,
      {
        title: "Star History",
        xLabel: props.chartMode === "Timeline" ? "Timeline" : "Date",
        yLabel: "GitHub Stars",
        data: {
          datasets: data.datasets,
        },
        showDots: true,
        transparent: false
      },
      {
        xTickLabelType: props.chartMode === "Date" ? "Date" : "Number",
        envType: "browser",
      }
    );
  }
};

onMounted(() => {
  if (props.data) {
    drawStarChart(props.data);
  }

  // Scale chart to a suitable mobile view.
  if (window.innerWidth < MIN_CHART_WIDTH) {
    if (chartContainerElRef.value) {
      const scaleRate = window.innerWidth / MIN_CHART_WIDTH;
      chartContainerElRef.value.style.marginTop = "8px";
      chartContainerElRef.value.style.transform = `scale(${scaleRate})`;

      if (chartContainerElRef.value.parentElement) {
        chartContainerElRef.value.parentElement.style.minHeight = "0";
        chartContainerElRef.value.parentElement.style.height = `${
          chartContainerElRef.value.clientHeight * scaleRate + 16
        }px`;
      }
    }
  }
});

onUpdated(() => {
  if (props.data) {
    drawStarChart(props.data);
  }
});

const handleSVGElementClick = () => {
  // Maybe we can capture the clicked svg element to expand chart functions.
};
</script>
